home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / lib / stdio / fread.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  2KB  |  109 lines

  1.  
  2. /*
  3.  *  FREAD.C
  4.  *
  5.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  6.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  7.  *    DICE-LICENSE.TXT.
  8.  *
  9.  *  fread does not return EOF unless an error occurs.  fread returns
  10.  *  0 or < elms when the end of file is reached.
  11.  */
  12.  
  13. #include <fcntl.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <lib/misc.h>
  18.  
  19. #define buf ((char *)vbuf)
  20.  
  21. size_t
  22. fread(vbuf, elmsize, elms, fi)
  23. void *vbuf;
  24. size_t elmsize;
  25. size_t elms;
  26. FILE *fi;
  27. {
  28.     int bytes;
  29.     int origBytes;
  30.  
  31.     if (elmsize == 1)
  32.     bytes = elms;
  33.     else if (elms == 1)
  34.     bytes = elmsize;
  35.     else
  36.     bytes = elms * elmsize;
  37.  
  38.     origBytes = bytes;
  39.  
  40.     if (fi && (fi->sd_Flags & __SIF_READ) && !fi->sd_Error) {
  41.     int n = 0;    /*  actual read */
  42.  
  43.     if (bytes == 0 || (fi->sd_Flags & __SIF_EOF))
  44.         return(0);
  45.  
  46.     if (fi->sd_UC >= 0) {       /*  ungotten character */
  47.         *buf = fi->sd_UC;
  48.         vbuf = buf + 1;
  49.         fi->sd_UC = -1;
  50.         --bytes;
  51.         ++n;
  52.     }
  53.     if (fi->sd_RLeft > 0) {
  54.         int nn = (fi->sd_RLeft > bytes) ? bytes : fi->sd_RLeft;
  55.  
  56.         movmem(fi->sd_RPtr, buf, nn);
  57.         fi->sd_RPtr += nn;
  58.         fi->sd_RLeft -= nn;
  59.         vbuf = buf + nn;
  60.         bytes -= nn;
  61.         n += nn;
  62.     }
  63.     if (bytes) {
  64.         if (bytes < fi->sd_BufSiz) {
  65.         if (_filbuf(fi))        /*  on no more data return n    */
  66.             goto skip;
  67.         }
  68.         if (fi->sd_RLeft <= 0) {    /*  unbuffered read or too-large read */
  69.         int nn;
  70.  
  71.         nn = read(fi->sd_Fd, buf, bytes);
  72.         if (nn < 0) {
  73.             if (n == 0)
  74.             n = -1;
  75.         } else {
  76.             if (nn == 0 && n == 0) {
  77.             if (fi->sd_Flags & __SIF_EOF)
  78.                 n = -1;
  79.             fi->sd_Flags |= __SIF_EOF;
  80.             }
  81.             fi->sd_Offset += nn;
  82.             n += nn;
  83.         }
  84.         } else {
  85.         if (fi->sd_RLeft < bytes)
  86.             bytes = fi->sd_RLeft;
  87.         movmem(fi->sd_RPtr, buf, bytes);
  88.         fi->sd_RPtr += bytes;
  89.         fi->sd_RLeft -= bytes;
  90.         n += bytes;
  91.         }
  92.     }
  93. skip:
  94.     if (n < 0) {
  95.         fi->sd_Error = EOF;
  96.         fi->sd_Flags |= __SIF_EOF;    // make sure this flag is set too
  97.     }
  98.     if (fi->sd_Error)
  99.         return(fi->sd_Error);
  100.     if (n == origBytes)
  101.         return(elms);
  102.     if (n == 0)
  103.         return(0);
  104.     return(n / elmsize);
  105.     }
  106.     return(0);
  107. }
  108.  
  109.